package model

import (
	"encoding/json"
	"fmt"
	"github.com/lib/pq"
)

type UpgradeStrategyCreateRequest struct {
	Id                  int64           `json:"id"`
	FirmwareIds         pq.Int64Array   `json:"firmware_ids"`
	Name                string          `json:"name"`
	UpgradeType         int             `json:"upgrade_type"`
	Order               json.RawMessage `json:"order"`
	FailureNotifyMethod int             `json:"failure_notify_method"`
	RetryCount          int             `json:"retry_count"`
	CreatedAt           int64           `json:"created_at"`
	UpdatedAt           int64           `json:"updated_at"`
}

type OrderType json.RawMessage

func (o OrderType) CheckOrder() error {

	var orders []UpgradeStrategyOrder
	_ = json.Unmarshal(o, &orders)

	var dup = map[int]struct{}{}
	for _, order := range orders {
		if len(order.Order) > 1 {
			return fmt.Errorf("invalid order.order length max is 1 %v", order.Order)
		}

		if _, ok := dup[order.FirmwareId]; ok {
			return fmt.Errorf("firmware_id must unique, %d duplicate", order.FirmwareId)
		}
		dup[order.FirmwareId] = struct{}{}
	}
	return nil
}

type UpgradeStrategyUpdateRequest struct {
	Id                  *int64          `json:"id"`
	FirmwareIds         pq.Int64Array   `json:"firmware_ids"`
	Name                *string         `json:"name"`
	UpgradeType         *int            `json:"upgrade_type"`
	Order               json.RawMessage `json:"order"`
	FailureNotifyMethod *int            `json:"failure_notify_method"`
	RetryCount          *int            `json:"retry_count"`
	CreatedAt           *int64          `json:"created_at"`
	UpdatedAt           *int64          `json:"updated_at"`
}
type UpgradeStrategyListRequest struct {
	Id                  *int64          `json:"id"`
	FirmwareId          *int64          `json:"firmware_id"`
	FirmwareIds         pq.Int64Array   `json:"firmware_ids"`
	Name                *string         `json:"name"`
	UpgradeType         *int            `json:"upgrade_type"`
	Order               json.RawMessage `json:"order"`
	FailureNotifyMethod *int            `json:"failure_notify_method"`
	RetryCount          *int            `json:"retry_count"`
	CreatedAt           *int64          `json:"created_at"`
	UpdatedAt           *int64          `json:"updated_at"`
	Index               int             `json:"index"`
	Size                int             `json:"size"`
}
type UpgradeStrategyDeleteRequest struct {
	Id int64 `json:"id"`
}

type UpgradeStrategyListResponse struct {
	Total int                    `json:"total"`
	List  []*UpgradeStrategyInfo `json:"list"`
}
type UpgradeStrategyInfoRequest struct {
	Id int64 `json:"id"`
}

type UpgradeStrategyInfo struct {
	Id                  int64           `json:"id"`
	FirmwareIds         pq.Int64Array   `json:"firmware_ids"`
	Name                string          `json:"name"`
	UpgradeType         int             `json:"upgrade_type"`
	Order               json.RawMessage `json:"order"`
	FailureNotifyMethod int             `json:"failure_notify_method"`
	RetryCount          int             `json:"retry_count"`
	CreatedAt           int64           `json:"created_at"`
	UpdatedAt           int64           `json:"updated_at"`
}
type UpgradePlanDetail struct {
	UpgradeType int    `json:"upgrade_type"`
	FirmwareId  int64  `json:"firmware_id"`
	Version     string `json:"version"`
	Name        string `json:"name"`
	FilePath    string `json:"file_path"`
	FileSize    int    `json:"file_size"`
	Description string `json:"description"`
	//Type        []FirmwareTypeDetail `json:"type"`
	Type json.RawMessage `json:"type"`
}

type UpgradeStrategyOrder struct {
	FirmwareId int `json:"firmware_id"`
	Order      []struct {
		Id   int    `json:"id"`
		Name string `json:"name"`
	} `json:"order"`
}

type UserUpgradeStatusDetail []UserUpgradeStatusDetailItem

func (d UserUpgradeStatusDetail) Json() json.RawMessage {
	bb, _ := json.Marshal(d)
	return bb
}

func (d UserUpgradeStatusDetail) Index(deviceType int) int {

	var index int
	for i, v := range d {
		if v.DeviceType == deviceType {
			index = i
		}
	}
	return index
}

func (d UserUpgradeStatusDetail) CalcTotalProgress() float32 {

	var totalProgress float32
	for _, v := range d {
		totalProgress += v.Progress
	}

	return totalProgress / float32(len(d))
}

type UserUpgradeStatusDetailItem struct {
	FirmwareTypeName string  `json:"firmware_type_name"`
	FirmwareId       int64   `json:"firmware_id"`
	DeviceType       int     `json:"device_type"`
	Status           int     `json:"status"`
	Progress         float32 `json:"progress"`
}
